﻿/******************************************************************************************
*                                                                                         *    
*                              Developed by Bruno Pires                                   *
*                                                                                         *
*                             email: bruno@blastersystems.com                             *
*                               web: www.blastersystems.com                               *
*                              blog: www.blastersystems.com/blog                          *
*                           twitter: brunoacpires                                         *
*                                                                                         *
*                      Software available under GNU LGPL License                          *
*                                                                                         *    
* *****************************************************************************************/

using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System;

namespace DataValidator
{
    public class FunctionsLibrary
    {
        public static bool AlgoritmoBi(string nbi)
        {
            var nbiArray = nbi.ToCharArray();

            int sum = 0;

            for (int pos = 0; pos < 8; ++pos)
            {
                sum += int.Parse(nbiArray[pos].ToString()) * (9 - pos);
            }

            int ctl = 0;
            if ((sum % 11) != 0)
                ctl = (11 - sum % 11) % 10;

            if (ctl == int.Parse(nbiArray[8].ToString()))
                return true;
            else
                return false;
        }

        public static bool IsNumeric(string inputString)
        {
            return Regex.IsMatch(inputString, "^[0-9]+$");
        }

        /// <summary>
        /// Constoi o uri e executa a chamada do webservice
        /// </summary>
        /// <param name="distrito"></param>
        /// <param name="concelho"></param>
        /// <param name="local"></param>
        /// <param name="rua"></param>
        /// <param name="porta"></param>
        /// <param name="codpos"></param>
        /// <param name="cliente"></param>
        /// <param name="pag"></param>
        /// <returns>Devolve o XML de resposta do serviço</returns>
        public string WebServiceRequestUri(string distrito, string concelho, string local, string rua, string porta, string codpos, string cliente, string pag)
        {
            string result = string.Empty;
            string andRequest = "&";
            int nParam = 0;

            StringBuilder uriRequest = new StringBuilder("http://www.ctt.pt/pdcp/xml_pdcp?");

            if (distrito != null && distrito != string.Empty)
            {
                uriRequest.Append("inDistrito=");
                uriRequest.Append(distrito.Replace(" ", "+"));
                nParam++;
            }

            if (concelho != null && concelho != string.Empty)
            {
                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inConcelho=");
                uriRequest.Append(concelho.Replace(" ", "+"));
                nParam++;
            }

            if (local != null && local != string.Empty)
            {
                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inLocal=");
                uriRequest.Append(local.Replace(" ", "+"));
                nParam++;
            }

            if (rua != null && rua != string.Empty)
            {
                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inRua=");
                uriRequest.Append(rua.Replace(" ", "+"));
                nParam++;
            }

            if (codpos != null && codpos != string.Empty)
            {
                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inCodPos=");
                uriRequest.Append(codpos.Replace(" ", "+"));
                nParam++;
            }

            if (porta != null && porta != string.Empty)
            {
                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inPorta=");
                uriRequest.Append(porta.Replace(" ", "+"));
                nParam++;
            }

            if (cliente != null && cliente != string.Empty)
            {
                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inCliente=");
                uriRequest.Append(cliente.Replace(" ", "+"));
                nParam++;
            }

            if (pag != null && pag != string.Empty)
            {

                if (nParam != 0)
                    uriRequest.Append(andRequest);

                uriRequest.Append("inPag=");
                uriRequest.Append(pag.Replace(" ", "+"));
                nParam++;
            }

            return uriRequest.ToString();
        }

        /// <summary>
        /// Executa a chamada do webservice
        /// </summary>
        /// <param name="uriRequest">URI de request</param>
        /// <returns>Retorna o XML de resposta construido pelo webservice</returns>
        public XDocument WebServiceResponseXml(string uriRequest)
        {
            var request = WebRequest.Create(uriRequest.ToString()) as HttpWebRequest;

            using (var response = request.GetResponse() as HttpWebResponse)
            {
                //28591 -> iso-8859-1
                var stream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(28591)); 
                var xmlDoc = XDocument.Load(stream);
                                
                return xmlDoc;

            }
        }

        /// <summary>
        /// Processa o ficheiro XML de resposta do webservice
        /// </summary>
        /// <param name="xmlDoc">Ficheiro XML de resposta</param>
        /// <returns>Devolve um objecto do tipo Morada</returns>
        public Morada ProcessXmlResponse(XDocument xmlDoc)
        {
            var result = new Morada();

            try
            {
                if (xmlDoc.Element("Erro") != null)
                    throw new Exception("A pesquisa não retornou resultados");
                var nRes = xmlDoc.Element("OK").Element("Result").Attribute("fim");

                var res = (from p in xmlDoc.Element("OK").Element("Result").Elements("Pagina").Attributes("fim")
                           select p.Value).First();

                if (int.Parse(res) != 1)
                {
                    return null;
                }
                else
                {

                    var queryResult = (from r in xmlDoc.Element("OK").Element("Localidade").Elements()
                                       select r).ToList();

                    
                    result.Designacao = queryResult[0].Value;
                    result.Distrito = queryResult[1].Value;
                    result.Concelho = queryResult[2].Value;
                    result.Freguesia = queryResult[4].Elements("Rua").Elements("Freguesia").First().Value; ;
                    result.Rua = queryResult[4].Elements("Rua").Elements("Designacao").First().Value;


                    var nCountTroco = queryResult[4].Elements("Rua").Select(p => p.Descendants("Trocos").Elements());

                    if (nCountTroco.FirstOrDefault().Count() > 0)
                    {
                        result.CodigoPostalCp4 = queryResult[4].Elements("Rua").Elements("Trocos").Elements("Troco").Elements("CodPos").Elements("CP4").First().Value;
                        result.CodigoPostalCp3 = queryResult[4].Elements("Rua").Elements("Trocos").Elements("Troco").Elements("CodPos").Elements("CP3").First().Value;
                        result.CodigoPostalDesignacao = queryResult[4].Elements("Rua").Elements("Trocos").Elements("Troco").Elements("CodPos").Elements("Designacao").First().Value;
                    }
                    else
                    {
                        result.CodigoPostalCp4 = queryResult[4].Elements("Rua").Elements("CodPos").Elements("CP4").First().Value;
                        result.CodigoPostalCp3 = queryResult[4].Elements("Rua").Elements("CodPos").Elements("CP3").First().Value;
                        result.CodigoPostalDesignacao = queryResult[4].Elements("Rua").Elements("CodPos").Elements("Designacao").First().Value;
                    }
                    return result;
                }
            }
            catch(Exception ex)
            {
                //falta identificar os vários tipos de erros

                result.TipoErro = ex.Message;
                return result;
            }
        }

    }
}
